from mcp.server.fastmcp import FastMCP
from PIL import Image, ImageDraw, ImageFont

mcp = FastMCP("TextImageService")

def create_background(width: int, height: int, bg_color: str, texture: str = None, corner_radius: int = 0) -> Image.Image:
    """创建背景图片
    Args:
        width: 图片宽度
        height: 图片高度
        bg_color: 背景颜色，Hex格式
        texture: 背景材质图片路径，可选
        corner_radius: 圆角半径，默认为0（直角）
    Returns:
        PIL.Image.Image: 背景图片（当corner_radius>0时为RGBA格式，否则为RGB格式）
    """
    bg_rgb = tuple(int(bg_color.lstrip('#')[i:i+2], 16) for i in (0, 2, 4))
    
    if texture:
        try:
            texture_img = Image.open(texture).convert('RGB')
            texture_img = texture_img.resize((width, height))
            bg_img = Image.new('RGB', (width, height), color=bg_rgb)
            blended_img = Image.blend(bg_img, texture_img, alpha=0.5)
        except:
            blended_img = Image.new('RGB', (width, height), color=bg_rgb)
    else:
        blended_img = Image.new('RGB', (width, height), color=bg_rgb)
    
    if corner_radius > 0:
        # 创建带透明通道的图像
        result = Image.new('RGBA', (width, height), (0, 0, 0, 0))
        
        # 创建圆角蒙版
        mask = Image.new('L', (width, height), 0)
        draw = ImageDraw.Draw(mask)
        draw.rounded_rectangle([(0, 0), (width, height)], corner_radius, fill=255)
        
        # 应用圆角
        rgb_img = Image.new('RGB', (width, height))
        rgb_img.paste(blended_img, (0, 0))
        result.paste(rgb_img, (0, 0), mask)
        return result
    
    return blended_img

def load_font(font_path: str, font_size: int) -> ImageFont.FreeTypeFont:
    """加载字体
    Args:
        font_path: 字体文件路径
        font_size: 字体大小
    Returns:
        ImageFont.FreeTypeFont: 字体对象
    """
    try:
        return ImageFont.truetype(font_path, font_size)
    except:
        return ImageFont.truetype('simhei.ttf', font_size)

def wrap_text(draw: ImageDraw.Draw, text: str, font: ImageFont.FreeTypeFont, width: int) -> list:
    """自动换行文本
    Args:
        draw: ImageDraw对象
        text: 要换行的文本
        font: 字体对象
        width: 最大宽度
    Returns:
        list: 分割后的行列表
    """
    lines = []
    
    # 先按用户输入的换行符分割文本
    paragraphs = text.split('\n')
    
    for paragraph in paragraphs:
        current_line = ""
        
        for char in paragraph:
            test_line = current_line + char
            test_bbox = draw.textbbox((0, 0), test_line, font=font)
            test_width = test_bbox[2] - test_bbox[0]
            
            if test_width <= width:
                current_line = test_line
            else:
                lines.append(current_line)
                current_line = char
        
        if current_line:
            lines.append(current_line)
    
    return lines

@mcp.tool()
def text_to_image(text: str, text_color: str = "#000000", bg_color: str = "#FFFFFF", 
                 width: int = 1080, height: int = 1080, font_size: int = 80, 
                 font_path: str = 'simhei.ttf', texture: str = None,
                 output_path: str = None, corner_radius: int = 0) -> Image.Image:
    """将文本转换为图片
    Args:
        text: 要转换为图片的文本
        text_color: 文字颜色，Hex格式，默认黑色(#000000)
        bg_color: 背景颜色，Hex格式，默认白色(#FFFFFF)
        width: 图片宽度，默认1080
        height: 图片高度，默认1080
        font_size: 字体大小，默认80
        font_path: 字体文件路径，默认'simhei.ttf'
        texture: 背景材质图片路径，可选
        output_path: 图片保存路径，可选
        corner_radius: 图片圆角半径，默认为0（直角）
    Returns:
        PIL.Image.Image: 生成的图片对象
    """
    # 创建背景
    image = create_background(width, height, bg_color, texture, corner_radius)
    draw = ImageDraw.Draw(image)
    
    # 加载字体
    font = load_font(font_path, font_size)
    
    # 计算文字颜色
    text_rgb = tuple(int(text_color.lstrip('#')[i:i+2], 16) for i in (0, 2, 4))
    
    # 计算文字边界框
    text_bbox = draw.textbbox((0, 0), text, font=font)
    text_height = text_bbox[3] - text_bbox[1]
    
    # 自动换行处理
    if draw.textbbox((0, 0), text, font=font)[2] - text_bbox[0] > width:
        lines = wrap_text(draw, text, font, width)
        total_height = len(lines) * text_height
        y = (height - total_height) / 2
        
        for line in lines:
            text_bbox = draw.textbbox((0, 0), line, font=font)
            text_width = text_bbox[2] - text_bbox[0]
            x = (width - text_width) / 2
            
            # 根据字体大小动态调整间距
            char_spacing = font_size * 0.1  # 字符间距为字体大小的10%
            line_spacing = font_size * 0.3  # 行间距为字体大小的30%
            
            # 绘制带间距的文本
            for i, char in enumerate(line):
                char_bbox = draw.textbbox((0, 0), char, font=font)
                char_width = char_bbox[2] - char_bbox[0]
                draw.text((x, y), char, font=font, fill=text_rgb)
                x += char_width + char_spacing
                
            y += text_height + line_spacing
    else:
        # 单行文本居中显示（带字符间距）
        text_width = text_bbox[2] - text_bbox[0]
        x = (width - text_width) / 2
        y = (height - text_height) / 2
        
        # 根据字体大小动态调整字符间距
        char_spacing = font_size * 0.1  # 字符间距为字体大小的10%
        
        # 绘制带间距的文本
        for char in text:
            char_bbox = draw.textbbox((0, 0), char, font=font)
            char_width = char_bbox[2] - char_bbox[0]
            draw.text((x, y), char, font=font, fill=text_rgb)
            x += char_width + char_spacing

    # image.save("output.png")
    # image.show()  # 显示图片，用于调试
    
    if output_path:
        image.save(output_path)
        
    # 返回图片数据
    return image

if __name__ == "__main__":
    text_to_image("文字\n图片")
    mcp.run(transport="stdio")